package cn.mianshiyi.braumdatasource.apollo;


import cn.mianshiyi.braumclient.ratelimit.rule.LimitRuleConfig;
import cn.mianshiyi.braumclient.utils.EasyStringUtil;
import cn.mianshiyi.braumdatasource.AbstractDataSource;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.ConfigService;
import com.ctrip.framework.apollo.model.ConfigChange;

import java.util.List;

/**
 * @author shangqing.liu
 */
public class ApolloDataSource extends AbstractDataSource {
    private String appId;
    private String key;
    private String serverMetaAddr;
    private String namespaceName;
    private Config config;

    public ApolloDataSource(String appId, String namespaceName, String key, String serverMetaAddr) {
        if (EasyStringUtil.isEmpty(appId) || EasyStringUtil.isEmpty(namespaceName) || EasyStringUtil.isEmpty(key) || EasyStringUtil.isEmpty(serverMetaAddr)) {
            throw new IllegalArgumentException(String.format("apollo argument is not allow null: appId=[%s], " +
                            "namespaceName=[%s], key=[%s], serverMetaAddr=[%s]",
                    appId, namespaceName, key, serverMetaAddr));
        }
        this.appId = appId;
        this.key = key;
        this.serverMetaAddr = serverMetaAddr;
        this.namespaceName = namespaceName;
        System.setProperty("app.id", appId);
        System.setProperty("apollo.meta", serverMetaAddr);
        this.config = ConfigService.getConfig(namespaceName);
        config.addChangeListener(changeEvent -> {
            for (String changeKey : changeEvent.changedKeys()) {
                if (!key.equals(changeKey)) {
                    continue;
                }
                ConfigChange change = changeEvent.getChange(changeKey);
                List<LimitRuleConfig> limitRuleConfigs = JSON.parseObject(change.getNewValue(),
                        new TypeReference<List<LimitRuleConfig>>() {
                        });
                ApolloDataSource.super.updateConfig(limitRuleConfigs);
            }
        });
        //初始化外部规则
        initConfig();
    }

    @Override
    protected List<LimitRuleConfig> loadAllConfig() {
        String value = config.getProperty(key, null);
        if (EasyStringUtil.isEmpty(value)) {
            return null;
        }
        return JSON.parseObject(value,
                new TypeReference<List<LimitRuleConfig>>() {
                });
    }

}
